<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
	<title>UI Settings</title>
	<script>
	var d = document;
	var loc = false, locip, locproto = "http:";
	var initial_ds, initial_st, initial_su;
	var sett = null;
	var l = {
		"comp":{
			"labels":"显示按钮标签",
			"colors":{
				"LABEL":"颜色选择方法",
				"picker": "色轮",
				"rgb": "RGB滑块",
				"quick": "快速颜色选择器",
				"hex": "十六进制颜色输入"
				},
			"pcmbot": "在PC模式下显示底部标签栏",
			"pid": "显示预设ID",
			"seglen": "设置片段长度不停止LED",
			"segpwr": "隐藏片段电源&亮度",
			"segexp" : "总是展开第一片段",
			"css": "启用自定义CSS",
			"hdays": "启用自定义节日列表",
			"fxdef": "使用效果默认参数"
		},
		"theme":{
			"alpha": {
				"bg":"背景透明度",
				"tab":"按钮透明度"
			},
			"bg":{
				"url":"背景图片链接",
				"random":"随机背景图片"
			},
			"color":{
				"bg":"背景十六进制颜色"
			}
		}
	};
	function gId(s) { return d.getElementById(s); }
	function toggle(el) { gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide"); }
	function isObject(item) {
		return (item && typeof item === 'object' && !Array.isArray(item));
	}
	function set(path, obj, val) {
		var tar = obj;
		var pList = path.split('_');
		var len = pList.length;
		for(var i = 0; i < len-1; i++) {
			var elem = pList[i];
			if( !tar[elem] ) tar[elem] = {}
			tar = tar[elem];
		}
		tar[pList[len-1]] = val;
	}
	var timeout;
	function showToast(text, error = false)
	{
		var x = gId("toast");
		x.innerHTML = text;
		x.classList.add(error ? "error":"show");
		clearTimeout(timeout);
		x.style.animation = 'none';
		timeout = setTimeout(function(){ x.classList.remove("show"); }, 2900);
	}
	function addRec(s, path = "", label = null)
	{
		var str = "";
		for (i in s)
		{
			var fk = path + (path?'_':'') + i;
			if (isObject(s[i])) {
				if (label && label[i] && label[i]["LABEL"]) str += `<h3>${label[i]["LABEL"]}</h3>`;
				str += addRec(s[i], fk, label? label[i] : null);
			} else {
				var lb = fk;
				if (label && label[i]) lb = label[i];
				else if (s[i+'LABEL']) lb = s[i+'LABEL'];
				if (i.indexOf('LABEL') > 0) continue;
				var t = typeof s[i];
				if (gId(fk)) { //already exists
					if(t === 'boolean')
					{
						gId(fk).checked = s[i];
					} else {
						gId(fk).value = s[i];
					}
					if (gId(fk).previousElementSibling.matches('.l')) {
						gId(fk).previousElementSibling.innerHTML = lb;
					}
				} else {
					if(t === 'boolean')
					{
						str += `${lb}: <input class="agi cb" type="checkbox" id=${fk} ${s[i]?"checked":""}><br>`;
					} else if (t === 'number')
					{
						str += `${lb}: <input class="agi" type="number" id=${fk} value=${s[i]}><br>`;
					} else if (t === 'string')
					{
						str += `${lb}:<br><input class="agi" id=${fk} value=${s[i]}><br>`;
					}
				}
			}
		}
		return str;
	}

	function genForm(s) {
		var str = "";
		str = addRec(s,"",l);
		
		gId('gen').innerHTML = str;
	}
	function GetLS()
	{
		sett = localStorage.getItem('wledUiCfg');
		if (!sett) gId('lserr').style.display = "inline";
		try {
			sett = JSON.parse(sett);
		} catch (e) {
			sett = {};
			gId('lserr').style.display = "inline";
			gId('lserr').innerHTML = "&#9888; Settings JSON parsing failed. (" + e + ")";
		}
		genForm(sett);
		gId('dm').checked = (gId('theme_base').value === 'light');
	}

	function SetLS()
	{
		var l = d.querySelectorAll('.agi');
		for (var i = 0; i < l.length; i++) {
			var e = l[i];
			var val = e.classList.contains('cb') ? e.checked : e.value;
			set(e.id, sett, val);
			console.log(`${e.id} set to ${val}`);
		}
		try {
			localStorage.setItem('wledUiCfg', JSON.stringify(sett));
			gId('lssuc').style.display = "inline";
		} catch (e) {
			gId('lssuc').style.display = "none";
			gId('lserr').style.display = "inline";
			gId('lserr').innerHTML = "&#9888; Settings JSON saving failed. (" + e + ")";
		}
	}

	function cLS()
	{
		localStorage.removeItem('wledP');
		localStorage.removeItem('wledPmt');
		localStorage.removeItem('wledPalx');
		showToast("Cleared.");
	}
	
	function Save() {
		SetLS();
		if (d.Sf.DS.value != initial_ds || d.Sf.ST.checked != initial_st || d.Sf.SU.checked != initial_su) d.Sf.submit();
	}
	
	// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
	function loadJS(FILE_URL, async = true) {
		let scE = d.createElement("script");
		scE.setAttribute("src", FILE_URL);
		scE.setAttribute("type", "text/javascript");
		scE.setAttribute("async", async);
		d.body.appendChild(scE);
		// success event 
		scE.addEventListener("load", () => {
			//console.log("File loaded");
			GetV(); 
			initial_ds = d.Sf.DS.value;
			initial_st = d.Sf.ST.checked;
			initial_su = d.Sf.SU.checked;
			GetLS();
		});
		// error event
		scE.addEventListener("error", (ev) => {
			console.log("加载文件错误", ev);
			alert("加载配置脚本失败。\n页面数据不完整！");
		});
	}
	function S() {
		let l = window.location;
		if (l.protocol == "file:") {
			loc = true;
			locip = localStorage.getItem('locIp');
			if (!locip) {
				locip = prompt("文件模式。请输入WLED IP！");
				localStorage.setItem('locIp', locip);
			}
		} else {
			// detect reverse proxy
			let path = l.pathname;
			let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
			if (paths.length > 2) {
				locproto = l.protocol;
				loc = true;
				locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths[0];
			}
		}
		loadJS(getURL('/settings/s.js?p=3'), false);	// If we set async false, file is loaded and executed, then next statement is processed
		if (loc) d.Sf.action = getURL('/settings/ui');
	}
	function getURL(path) {
		return (loc ? locproto + "//" + locip : "") + path;
	}
	function H() { window.open("https://kno.wled.ge/features/settings/#user-interface-settings"); }
	function B() { window.open(getURL("/settings"),"_self"); }
	function UI()
	{
		gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
		var f = gId('theme_base');
		if (f) f.value = (gId('dm').checked) ? 'light':'dark';
	}

	// random BG image
	function setRandomBg() {
		if (gId("theme_bg_random").checked) {
			gId("theme_bg_url").value = "https://picsum.photos/1920/1080";
		} else {
			gId("theme_bg_url").value = "";
		}
		
	}
	function checkRandomBg() {
		if (gId("theme_bg_url").value === "https://picsum.photos/1920/1080") {
			gId("theme_bg_random").checked = true;
		} else {
			gId("theme_bg_random").checked = false;
		}
	}
	function uploadFile(fO,name) {
		var req = new XMLHttpRequest();
		req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)});
		req.addEventListener('error', function(e){showToast(e.stack,true);});
		req.open("POST", "/upload");
		var formData = new FormData();
		formData.append("data", fO.files[0], name);
		req.send(formData);
		fO.value = '';
		return false;
	}
	</script>
	<style>@import url("style.css");</style>
</head>
<body onload="S()">
	<form id="form_s" name="Sf" method="post">
		<div class="toprow">
		<div class="helpB"><button type="button" onclick="H()">?</button></div>
		<button type="button" onclick="B()">后退</button><button type="button" onclick="Save()">保存</button><br>
		<span id="lssuc" style="color:green; display:none">&#10004; Local UI settings saved!</span>
		<span id="lserr" style="color:red; display:none">&#9888; Could not access local storage. Make sure it is enabled in your browser.</span><hr>
		</div>
		<h2>页面配置</h2>
		服务器描述：<input type="text" name="DS" maxlength="32"><br>
		同步按钮切换发送和接收：<input type="checkbox" name="ST"><br>
		<div id="NoSimple" class="hide">
			<i class="warn">此固件版本不包括简化的UI支持。<br></i>
		</div>
		<div id="Simple">启用简化界面: <input type="checkbox" name="SU"><br></div>
		<i>以下界面自定义设置对于WLED设备和此浏览器都是唯一的。<br>
		如果使用不同的浏览器、设备或WLED的IP地址，您需要重新设置它们。<br>
		刷新主界面以应用更改。</i><br>
		
		<div id="gen">加载设置...</div>
		
		<h3>界面外观</h3>
		<span class="l"></span>: <input type="checkbox" id="comp_labels" class="agi cb"><br>
		<span class="l"></span>: <input type="checkbox" id="comp_pcmbot" class="agi cb"><br>
		<span class="l"></span>: <input type="checkbox" id="comp_pid" class="agi cb"><br>
		<span class="l"></span>: <input type="checkbox" id="comp_seglen" class="agi cb"><br>
		<span class="l"></span>: <input type="checkbox" id="comp_segpwr" class="agi cb"><br>
		<span class="l"></span>: <input type="checkbox" id="comp_segexp" class="agi cb"><br>
		我讨厌黑暗（模式）： <input type="checkbox" id="dm" onchange="UI()"><br>
		<span id="idonthateyou" style="display:none"><i>为嘛这么做...</i>&#x1F97A;<br></span>
		<span class="l"></span>: <input type="number" min=0.0 max=1.0 step=0.01 id="theme_alpha_tab" class="agi"><br>
		<span class="l"></span>: <input type="number" min=0.0 max=1.0 step=0.01 id="theme_alpha_bg" class="agi"><br>
		<span class="l"></span>: <input type="text" id="theme_color_bg" maxlength="9" class="agi"><br>
		<span class="l">背景图片链接</span>: <input type="text" id="theme_bg_url" class="agi" oninput="checkRandomBg()"><br>
		<span class="l">随机背景图片</span>: <input type="checkbox" id="theme_bg_random" class="agi cb" onchange="setRandomBg()"><br>
		<input id="theme_base" class="agi" style="display:none">
		<span class="l"></span>: <input type="checkbox" id="comp_css" class="agi cb"><br>
		<div id="skin">自定义CSS：<input type="file" name="data" accept=".css"> <input type="button" value="上传" onclick="uploadFile(d.Sf.data,'/skin.css');"><br></div>
		<span class="l"></span>: <input type="checkbox" id="comp_hdays" class="agi cb"><br>
		<div id="holidays">节日： <input type="file" name="data2" accept=".json"> <input type="button" value="上传" onclick="uploadFile(d.Sf.data2,'/holidays.json');"><br></div>
		<div id="toast"></div>
		<hr><button type="button" onclick="cLS()">清除浏览器缓存</button>
		<hr><button type="button" onclick="B()">后退</button><button type="button" onclick="Save()">保存</button>
	</form>
</body>
</html>